package model;

import org.jbox2d.common.Vec2;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.geom.Polygon;
import org.newdawn.slick.geom.Shape;
import controller.Global;

public class Water {
	int MAXX = 64;
	int MAXY = 64;
	int DAMP = 64;
	int CT = 0, NW = 1;
	long t = 0, t1 = 0;
	float[][][] waveMap = new float[2][MAXX][MAXY];

	public Water() {
	}

	// update water
	public void update() {
		int x, y, Temporary_Value;
		float n;

		// timer sync to zoom level propagation kludge
		if (System.currentTimeMillis() > t) {
			t = System.currentTimeMillis() + ((int) (10f / Global.zoom));
		} else {
			return;
		}
		// add constant ripple
		if (System.currentTimeMillis() > t1) {
			t1 = System.currentTimeMillis() + 1200;
			waveMap[0][MAXX / 2][MAXY / 2] = -MAXY * 10f;
		}
		// calculate wave map intersection
		for (y = 1; y < MAXY - 1; y++) {
			for (x = 1; x < MAXX - 1; x++) {
				n = (float) ((waveMap[CT][x - 1][y] + waveMap[CT][x + 1][y]
						+ waveMap[CT][x][y - 1] + waveMap[CT][x][y + 1]) / 2 - waveMap[NW][x][y]);
				n = n - (n / DAMP);
				waveMap[NW][x][y] = n;
			}
		}
		Temporary_Value = CT;
		CT = NW;
		NW = Temporary_Value;
	}

	// generate impact on wave surface
	public void impact(float x, float f) {
		x = x / (Global.screenX / (((float) MAXX) - 1f));
		if (x > 0 && x < MAXX) {
			waveMap[0][(int) x][MAXY / 2] = -10 * MAXY * f;
		} else if (x <= 0) {
			waveMap[0][1][MAXY / 2] = -10 * MAXY * f;
		} else if (x >= MAXX) {
			waveMap[0][MAXX - 2][MAXY / 2] = -10 * MAXY * f;
		}
	}

	// get a polygon representation of the waves
	public Shape getPolygon() {
		float mean, my;
		Vec2 p = new Vec2(0, Global.waterLevel);
		p = Global.worldToScreen(p.x, p.y);
		p.y = (p.y < 0) ? -5f : p.y;
		Polygon poly = new Polygon();

		for (int x1 = 0; x1 < MAXX; x1++) {
			mean = 0;
			for (int y1 = 0; y1 < MAXY; y1++) {
				mean += waveMap[0][x1][y1];
			}
			mean = mean / ((float) MAXY);
			my = mean * Global.zoom;
			my = my + p.y;
			my = (my > Global.screenY) ? Global.screenY : my;
			poly.addPoint(((float) x1)
					* (Global.screenX / (((float) MAXX) - 1f)), my);
		}
		poly.addPoint(Global.screenX, Global.screenY);
		poly.addPoint(0, Global.screenY);

		return poly;
	}

	// get a polygon representation of the waves
	public Shape getPolygon(int level) {
		float my;
		Vec2 p = new Vec2(0, Global.waterLevel);
		p = Global.worldToScreen(p.x, p.y);
		p.y = (p.y < 0) ? -5f : p.y;
		Polygon poly = new Polygon();

		for (int x1 = 0; x1 < MAXX; x1++) {
			my = waveMap[0][x1][level] * Global.zoom;
			my = my + p.y;
			my = (my > Global.screenY) ? Global.screenY : my;

			poly.addPoint(((float) x1)
					* (Global.screenX / (((float) MAXX) - 1f)), my);
		}
		poly.addPoint(Global.screenX, Global.screenY);
		poly.addPoint(0, Global.screenY);

		return poly;
	}

	// render the water
	public void render(Graphics g, Image image) {
		Vec2 p = new Vec2(0, Global.waterLevel);
		p = Global.worldToScreen(p.x, p.y);
		p.y = (p.y < 0) ? -5f : p.y;

		g.texture(getPolygon(), image, 1, 1, true);

		 

		// g.setColor(new Color(255, 255, 255));
		// for (int i = 0; i < MAXX; i++) {
		// for (int j = 0; j < MAXY; j++) {
		// g.drawRect(i * 30, (waveMap[0][i][j] * Global.zoom) + p.y, 30, 1);
		// }
		// }
	}
}
